﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.ComponentModel;
using System.Windows.Threading;
using SKYPE4COMLib;

namespace SoundServant
{
    /// <summary>
    /// Interaction logic for LoadWindow.xaml
    /// </summary>
    public partial class ConnectingWindow : SSWindow
    {
        Skype skype;
        Listener listener;
        bool cancel = false;

        public ConnectingWindow(Skype _skype, Listener _listener)
        {
            InitializeComponent();
            
            skype = _skype;
            listener = _listener;

            ConnectingLabel.Content = "Connecting " + listener.Name;
            
            

        }

        private void SSWindow_ContentRendered(object sender, EventArgs e)
        {
           
                if (skype.ActiveCalls.Count > 0)
                {
                    System.Windows.Forms.Application.DoEvents();

                    // Check to see if any other listeners are currently dialing
                    bool okToRing = true;
                    foreach (Call call in skype.ActiveCalls) if (Sharing.IsCallRinging(call.Status)) okToRing = false;

                    if (okToRing)
                    {
                        try
                        {
                            Logs.Information("Skype", "Joining listener to Conference - Name: " + listener.Name + " Handle: " + listener.Contact);


                            // Put all calls on hold
                            Logs.Information("Skype", "Putting all calls on Hold");
                            foreach (Call call in skype.ActiveCalls)
                            {
                                if (Sharing.IsCallInProgress(call.Status)) call.Hold();
                            }

                            // Check all calls are on hold
                            Logs.Information("Skype", "Checking all calls are on hold");
                            bool allCallsOnHold;
                            do
                            {
                                allCallsOnHold = true;
                                foreach (Call call in skype.ActiveCalls)
                                {
                                    if (!Sharing.IsCallOnHold(call.Status)) allCallsOnHold = false;
                                }
                            }
                            while (!allCallsOnHold);

                            // Dial new Listener
                            Logs.Information("Skype", "Dialing new Listener - Name: " + listener.Name + " Handle: " + listener.Contact);
                            Call newCall = null;
                            try
                            {
                                newCall = skype.PlaceCall(listener.Contact, "", "", "");

                            }
                            catch
                            {
                                Logs.Information("Skype", "Failed to place new call");
                            }
                            Logs.Information("Skype", "Unholding all calls");

                            // Unhold all calls
                            foreach (Call call in skype.ActiveCalls)
                            {
                                if (Sharing.IsCallOnHold(call.Status)) call.Resume();
                            }

                            if (newCall != null)
                            {
                                Logs.Information("Skype", "Waiting for new call to succeed or fail");
                                // Wait for new call to Suceed or Fail
                                bool newCallSucceeded = false;
                                bool newCallFailed = false;
                                while (!newCallSucceeded && !newCallFailed)
                                {
                                    System.Windows.Forms.Application.DoEvents();
                                    if (cancel)
                                    {
                                        try
                                        {
                                            Logs.Information("Skype", "Canceling Conference Call Joiner");
                                            newCall.Finish();
                                        }
                                        catch(Exception _e)
                                        {

                                        }
                                        newCallFailed = true;
                                    }
                                    if (Sharing.IsCallInProgress(newCall.Status))
                                    {
                                        Logs.Information("Skype", "New call is in progress");
                                        newCallSucceeded = true;
                                    }
                                    /*if (IsCallRinging(newCall.Status))
                                    {
                                        Logs.Information("Skype", "New call is ringing");
                                        newCallSucceeded = true;
                                    }*/
                                    if (Sharing.HasCallFailed(newCall.Status)) newCallFailed = true;
                                    if (Sharing.HasCallFinished(newCall.Status)) newCallFailed = true;
                                    if (Sharing.IsAnswerMachine(newCall.Status)) newCallFailed = true;
                                    

                                }

                                Logs.Information("Skype", "Trying to join new call to old call");
                                if (newCallSucceeded)
                                {
                                    if (skype.ActiveCalls.Count > 1)
                                    {
                                        foreach (Call call in skype.ActiveCalls)
                                        {
                                            if (call.Id != newCall.Id && Sharing.IsCallInProgress(call.Status) && (Sharing.IsCallInProgress(newCall.Status) || Sharing.IsCallRinging(newCall.Status)))
                                            {
                                                // Join new call to main call
                                                Logs.Information("Skype", "Joining calls - New Call: " + newCall.Id + " Old Call: " + call.Id);
                                                newCall.Join(call.Id);
                                                break;
                                            }
                                        }
                                    }

                                }
                            }
                        }
                        catch (Exception excep)
                        {
                            Logs.Information("Skype", "Conference Call Joiner Error: " + excep.ToString());
                        }
                    }
                    else
                    {
                        SSMessageBox.Show("Skype", "Sorry, you cannot connect this listener right now, another listener is currently being connected.", SSMessageBoxType.Ok);
                    }
                    CloseConnectingWindow();
                }
            
            
        }

        private void CloseConnectingWindow()
        {
            this.Closing -= SSWindow_Closing;
            this.Close();
        }

        public static void RunConferenceJoiner(Skype _skype, Listener _listener)
        {
            ConnectingWindow connectingWindow = new ConnectingWindow(_skype, _listener);
            connectingWindow.ShowDialog();
        }

        private void SSWindow_Closing(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            cancel = true;
        }
    }
}
